Device & Device node

Device
Character Device
1. 키보드/마우스와 같이 흘러가는 데이터를 기반으로 바이트 단위 입출력
2. 블록 디바이스처럼 원한느 위치의 데이터에 직접 접근 불가능
3. 캐릭터 디바이스 노드라는 특수한 파일을 통해 접근
4. 응용 프로그램 디바이스 노드를 이용해 캐릭터 디바이스를 직접 사용
Block Device
1. 디스크와 같은 저장 장치로 블록 단위 입출력
2. 위치에 상관 없이 데이터에 접근할 수 있는 탐색 기능 지원
3. 블록 디바이스 노드라는 특수한 파일을 통해 접근
4. 파일 시스템으로 마운트하여 사용하는 것이 일반적
Network Device
1. 물리적인 어댑터와 특정 프로토콜을 이용해 네트워크에 접속하는 디바이스
2. 디바이스 노드 대신 전용 소켓 API를 통해 접근
Device Driver
1. 리눅스에서 각 디바이스를 제어하기 위한 프로그래밍 모델
    - 커널 모듈에 가상 파일시스템 인터페이스를 결합해 구현
    - 가상 파일시스템은 응용 프로그램에서 파일 입출력 API를 통해 접근 가능
2. 블록 디바이스는 블록 디바이스 드라이버로 제어
3. 캐릭터 디바이스는 캐릭터 디바이스 드라이버로 제어
4. 네트워크 디바이스는 네트워크 디바이스 드라이버로 제어

Device Node
Device를 나타내는 특수 파일
1. 특수 파일은 정규 파일과 같은 표준 시스템 호출을 통해 참조(open, close)
    - 주변 장치나 파이프, 소켓과 같은 프로세스 간 상호 통신 메커니즘에 해당
2. 임베디드 리눅스를 포함한 모든 리눅스 배포 버전은 /dev 경로에 노드들을 관례적으로 저장
노드 파일의 특징
1. 디바이스 노드는 그 자체가 파일 시스템에 존재하는 하나의 파일로 보임
    - 물리적인 저장소의 특정 파일 시스템에 위치하는 파일은 아님
2. 사용자 공간에서 메모리에 적재된 특정 디바이스 드라이버에 접근하는데 필요
노드 파일 생성
1. mknod라는 전용 유틸리티 사용
2. mknod /dev/node_name type major_number minor_number
    - type: b(block), c(character)
    - major_number: 디바이스 구분용(major_number가 다르면 다른 디바이스임을 의미)
    - minor_number: 동일한 디바이스가 여러개일 때 구분
        (커널이 아닌 디바이스 드라이버가 자체적으로 사용)

device driver & file_operations structure
- 디바이스 드라이버 처리 과정(process)
1. 응용 프로그램과 대응되는 커널 함수의 주소를 file_operations 구조체의 해당 필드에 대입
2. 디바이스 드라이버의 해당 관리 구조체에 file_operations 구조체 대입
3. 디바이스 드라이버의 전용 등록 함수를 통해 해당 관리 구조체 등록
4. /dev 경로에 노드 파일 생성
5. 응용 프로그램은 노드 파일을 이용해 파일 접근 관련 API 호출
6. 커널은 노드 파일에 연관된 file_operations 구조체를 탐색해 시스템 호출에 대응하는 해당 필드의 함수 호출
7. 모듈에서 구현한 사용자 함수가 호출됨
struct miscDevice{
int minor;
const char* name; //
// file_operations
const struct file_operations* fops;
struct list_head list;
struct device* parent;
struct device* this_device;
const char* nodename;
mode_t mode;
}
노드 파일과 file_operations을 연관시키는 device 구조체
1. 커널이 관리하는 드라이버 등록 및 해제 지원
    - 커널 내부에서는 device 구조체를 통해 관리한다.
2. 사용자가 시스템 호출을 통해 노드 파일에 접근할 때 file_operations 구조체에 연결

int minor
    - 노드 파일의 보조 번호(minor number)
    - 커널에서 동적으로 할당하기에 MISC_DYNAMIC_MINOR를 사용
const char* name
    - 노드 파일 이름
    - /dev 경로에 존재하는 파일 이름과 중복되지 않도록 주의
const struct file_operations* fops;
    - 사용자가 정의한 file_operations 구조체 할당!
struct file_operations_example{
open : example_open,
read : example_read,
write : example_write,
ioctl : example_ioctl,
release : example_release
};